home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-15 / ctest257.zip / TIME.PAS < prev    next >
Pascal/Delphi Source File  |  1992-02-05  |  3KB  |  70 lines

  1. UNIT Time;
  2.  
  3. INTERFACE
  4.  
  5. FUNCTION Clock: LONGINT;             { same as VMS; time in milliseconds }
  6.  
  7.  
  8. IMPLEMENTATION
  9.  
  10. FUNCTION Clock: LONGINT; ASSEMBLER;
  11. ASM
  12.              PUSH    DS              { save caller's data segment }
  13.              XOR     DX, DX          { initialize data segment to }
  14.              MOV     DS, DX          {  access ticker counter }
  15.              MOV     BX, 46Ch        { offset of ticker counter in segm.}
  16.              MOV     DX, 43h         { timer chip control port }
  17.              MOV     AL, 4           { freeze timer 0 }
  18.              PUSHF                   { save caller's int flag setting }
  19.              STI                     { allow update of ticker counter }
  20.              LES     DI, DS:[BX]     { read BIOS ticker counter }
  21.              OUT     DX, AL          { latch timer 0 }
  22.              LDS     SI, DS:[BX]     { read BIOS ticker counter }
  23.              IN      AL, 40h         { read latched timer 0 lo-byte }
  24.              MOV     AH, AL          { save lo-byte }
  25.              IN      AL, 40h         { read latched timer 0 hi-byte }
  26.              POPF                    { restore caller's int flag }
  27.              XCHG    AL, AH          { correct order of hi and lo }
  28.              MOV     CX, ES          { ticker counter 1 in CX:DI:AX }
  29.              CMP     DI, SI          { ticker counter updated ? }
  30.              JE      @no_update      { no }
  31.              OR      AX, AX          { update before timer freeze ? }
  32.              JNS     @no_update      { no }
  33.              MOV     DI, SI          { use second }
  34.              MOV     CX, DS          {  ticker counter }
  35. @no_update:  NOT     AX              { counter counts down }
  36.              MOV     BX, 36EDh       { load multiplier }
  37.              MUL     BX              { W1 * M }
  38.              MOV     SI, DX          { save W1 * M (hi) }
  39.              MOV     AX, BX          { get M }
  40.              MUL     DI              { W2 * M }
  41.              XCHG    BX, AX          { AX = M, BX = W2 * M (lo) }
  42.              MOV     DI, DX          { DI = W2 * M (hi) }
  43.              ADD     BX, SI          { accumulate }
  44.              ADC     DI, 0           {  result }
  45.              XOR     SI, SI          { load zero }
  46.              MUL     CX              { W3 * M }
  47.              ADD     AX, DI          { accumulate }
  48.              ADC     DX, SI          {  result in DX:AX:BX }
  49.              MOV     DH, DL          { move result }
  50.              MOV     DL, AH          {  from DL:AX:BX }
  51.              MOV     AH, AL          {   to }
  52.              MOV     AL, BH          {    DX:AX:BH }
  53.              MOV     DI, DX          { save result }
  54.              MOV     CX, AX          {  in DI:CX }
  55.              MOV     AX, 25110       { calculate correction }
  56.              MUL     DX              {  factor }
  57.              SUB     CX, DX          { subtract correction }
  58.              SBB     DI, SI          {  factor }
  59.              XCHG    AX, CX          { result back }
  60.              MOV     DX, DI          {  to DX:AX }
  61.              POP     DS              { restore caller's data segment }
  62. END;
  63.  
  64.  
  65. BEGIN
  66.    Port [$43] := $34;                { need rate generator, not square wave }
  67.    Port [$40] := 0;                  { generator as programmed by some BIOSes }
  68.    Port [$40] := 0;                  { for timer 0 }
  69. END. { Time }
  70.